package com.ruoyi.task.springsched2;

import com.ruoyi.common.utils.StringUtils;
import org.quartz.Scheduler;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.TimeZone;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @Author alison
 * @Date 2024/12/1 18:09
 * @Version 1.0
 * @Description
 */

@ComponentScan(basePackageClasses = AnnoSched.class)
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, QuartzAutoConfiguration.class})
@SpringBootTest
public class AnnoSched {

    public static void main(String[] args) throws Throwable {
        System.setProperty("spring.main.web-application-type", "none");
        System.setProperty("logging.level.root", "off");
        System.out.println("now  = " + LocalDateTime.now());
        ConfigurableApplicationContext context = SpringApplication.run(AnnoSched.class, args);
        TaskScheduler taskScheduler = context.getBean(TaskScheduler.class);//org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler
//        Scheduler scheduler = context.getBean(Scheduler.class);//org.quartz.impl.StdScheduler

//        ScheduledExecutorService scheduledExecutorService = context.getBean(ScheduledExecutorService.class); // ScheduledThreadPoolExecutor
//        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = context.getBean(ScheduledThreadPoolExecutor.class);
        Executor executor = context.getBean("taskExecutor", Executor.class);
        TimeUnit.SECONDS.sleep(3);
        ThreadPoolTaskExecutor threadPoolTaskExecutor = (ThreadPoolTaskExecutor) executor;
        ThreadPoolExecutor threadPoolExecutor = threadPoolTaskExecutor.getThreadPoolExecutor();
        int maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
        System.out.println("maximumPoolSize = " + maximumPoolSize);
        System.out.println("threadPoolTaskExecutor.toString() = " + threadPoolTaskExecutor.getThreadPoolExecutor());
        TimeUnit.SECONDS.sleep(10);
    }
}

// schedule 默认是使用只有一个线程去执行调度任务
@EnableAsync
@EnableScheduling
@Configuration
class SchedConfig {
    // 以固定延迟调度任务
    // 任务执行之后休息delay才调度
//    @Async
    @Scheduled(fixedDelay = 1000)
    public void scheduleFixedDelayTask() throws Exception {
        System.out.println("---------------------scheduleFixedDelayTask--------------------------");
        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
//        System.out.println("Fixed delay task - " + System.currentTimeMillis() / 1000);
        TimeUnit.SECONDS.sleep(1);
        System.out.println("delay now  = " + LocalDateTime.now());
    }

    // 以固定频率调度任务
    // 不考虑任务的执行时间，仅按照设定的固定速率调度任务. 如果执行时间长于rate时间,没有配置线程池就等待在执行,有配置就创建线程去执行
//    @Async
    @Scheduled(fixedRate = 1000, initialDelay = 1000)
    public void scheduleFixedRateTask() throws Exception {
        System.out.println("---------------------scheduleFixedRateTask------------------------");
        System.out.println("Thread.currentThread().getName() = " + Thread.currentThread().getName());
//        System.out.println("Fixed rate task - " + System.currentTimeMillis() / 1000);
        TimeUnit.SECONDS.sleep(2);
        System.out.println("rate now = " + LocalDateTime.now());
    }

    // 使用 Cron 表达式
    @Scheduled(cron = "0/2 * * * * ?")
    public void cronTask() throws Exception {
        System.out.println("cron task");
    }

    // 参数化调度时间
    @Scheduled(fixedDelayString = "${task.fixedDelay}", fixedRateString = "${task.fixedRate}", initialDelayString = "${task.initialDelay}")
    public void fixedSpEl() throws Exception {
        System.out.println("spel");
    }

    @Scheduled(cron = "${task.cron}")
    public void cronEl() {
    }

}
